A processor in a computer has at least two different operational modes. The first is typically referred to as “kernel mode” and the second may be referred to as “user mode”, although other terms have been used, e.g., instead of “user mode” the mode may be referred to as an “application mode”. The kernel mode is employed for core operating system (O.S.) functions, whereas the use mode is employed when the processor executes applications, i.e., computer programs directed to specific tasks that in turn rely on the O.S. Some device driver software may also be executed in the kernel mode.
Essentially, in the kernel mode the processor can access substantially all of the assets available to it. In contrast, in the user mode the processor is permitted to access only some, but not all, of the assets available to it. Limiting access in the user mode prevents an application executed by the processor from altering, and possibly damaging, critical operating system data.
Another feature of modern processors is cache memory, which is loaded with copies of selected data from main memory. Cache memory is faster than main memory, therefore accessing data in cache memory improves performance. In most cases, when the central processing unit (CPU) reads or writes main memory, a portion of the data cache (sometimes called a “cache block”) is automatically allocated to contain copies of data from a corresponding portion of main memory. The data cache records the corresponding main memory address for each cache block, so that future access to the same memory address will read or write the data cache rather than directly accessing main memory, thus improving performance. Various means may be used to associate portions of data cache with portions of memory. As a simple example, given a 32-bit memory address, where the least significant bit is numbered 0, an implementation could use address bits 15-8 to select one of 256 possible data cache blocks.
Because the faster cache memory is more expensive than main memory, it is generally smaller than main memory. As the CPU accesses different parts of main memory, the copies in the data cache may be “evicted” and those portions of the data cache may be reallocated to contain more recently accessed parts of main memory. If the CPU then accesses a memory address that has been evicted from the data cache, the access is slower, because that portion of memory must have a portion of the data cache reallocated and the data must be reloaded from main memory. This difference in performance can be detected by software executing in the CPU.
Cache memory, like main memory, is generally treated as a resource shared by kernel-mode and user-mode software. User-mode software generally cannot directly read kernel-mode data from the data cache. However, user-mode software can indirectly determine which portions of the data cache have been evicted and loaded with kernel-mode data by detecting the performance difference mentioned above.
It is also a feature of modern processors to speculatively execute some tasks out of order, before they are otherwise required, to promote efficiency. As a simple example, a calculation that depends on a condition may be executed ahead of time while the processor determines whether the condition is satisfied. If the condition eventually is determined to be satisfied, the calculation already has been done and the results can be used, shortening processing time. If the condition eventually is determined not to be satisfied, the speculative calculation can simply be discarded without loss of processing time, since it was done speculatively during the wait period to determine whether the condition is satisfied.
Recent malware known as “Spectre” and “Meltdown” seeks to exploit a combination of speculative execution and data cache behavior. Fundamentally, these “exploits” influence kernel-mode software to speculatively execute instructions that ultimately evict a portion of the data cache. By using performance characteristics to determine which portion was evicted, the “exploits” can indirectly derive values of protected kernel-mode data. Variants of Spectre and Meltdown may use different means to influence speculative execution, but they all derive values of kernel-mode data by detecting differences in data cache performance.